<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style>
    div, li, p {
      line-height: 40px;
    }
    span {
      color: red;
    }
  </style>
</head>
<body>
  <h3>async/await</h3>
  <ul>
    <li>async函数是什么？用一句话来说，它就是<span>Generator</span>函数的语法糖</li>
    <li>
      通过比较发现，async函数就是将Generator函数的星号（*）替换成async，将yield替换成await，仅此而已
    </li>
    <li>
      <h3>async函数的特点</h3>
      <ul>
        <li>内置执行器(Generator函数执行必须依赖执行器，所以才有了co模块)，而async函数<span>自带执行器</span></li>
        <li>更好的语义</li>
        <li>
          await命令后面，可以是原始类型的值，也可以是Promise对象,返回resolved值，<span>也是一个promise</span>
        </li>
      </ul>
    </li>
    <li>
      async函数内部return语句的返回值，会成为then方法回调函数的返回值
    </li>
    <li>
      async函数内部抛出的错误会导致返回的Promise对象变为reject状态。抛出的错误对象会被catch方法回调函数接收到
    </li>
    <li>
      async函数返回的Promise对象必须等到内部所有的await命令后面的Promise对象执行完毕才会发生状态改变。除非遇到return语句或者抛出错误，也就是说，只有async函数内部的异步操作才会执行完，才会执行then方法指定的回调函数
    </li>
    <li>
      有时候，我们希望即使前一个异步操作失败，也不要中断后面的异步操作。这时可以将第一个await放在try...catch结构里面，这样不管这个异步操作是否成功，第二个await都会执行
    </li>
    <li>
      捕获错误的时候，reject参数会传递到catch中，无论await前面是否加上了return
    </li>
    <li>
      如果一个await语句后面的Promise变为reject，那么整个async函数都会中断执行，有时，我们希望即使前一个异步操作失败，也不要中断后面的操作，处理方法是:
      <ul>
        <li>将这些可能发生错误的await放入trycatch里面，那些不期望中断执行的await放在函数的外面。</li>
        <li>在await后面的Promise对下个后添加一个catch方法，处理前面可能出现的错误</li>
        <li></li>
      </ul>
    </li>
    <li>
      多个await命令后面的异步操作如果不存在继发关系，最好让他们同时触发，节省运行时间
    </li>
    <li>
      await命令只能用在async函数中，如果用在普通函数中就会报错。如果确实希望多个请求并发执行，可以使用Promsie.all方法
    </li>
    <li>
      async函数的实现原理就是将Generator函数和自动执行器包装在一起，处理异步的时候，async函数的实现最简洁，最符合语义
    </li>
  </ul>
</body>
</html>